Raycastのスクリプト実行の引数で濁点・半濁点が分離してしまう問題を解決する

Raycastのスクリプト実行の引数で濁点・半濁点が分離してしまう問題を解決する

Clock Icon2024.05.30

Raycastを愛用しています! RaycastはMac専用のコマンドランチャーアプリです。 Alfredとほぼ同じことができると考えて良いかと思います。

Raycastの非常に気に入っている機能として、 シェルスクリプトなどをコマンドランチャーから簡単に実行することができる点があります。 やり方はこちらを参照してください。

この機能は省略可能な引数を受け取ることもできるので、 かなり利便性の高いスクリプトをホットキーで簡単に実行することができます。 控えめに言って最高です。

例えば私は自作のtodo管理アプリを使っているのですが、 タスク追加のAPIを実装して、 それを叩くようなスクリプトを叩くことでタスクを追加しています。 こんな感じです。 ちなみに与えられる引数の数は3つまでに制限されています。1

タスク追加は思いついた瞬間にできるだけ少ない手数で登録できることが重要なので、 todo管理アプリをアクティブにしてる暇なんてないのです。 そんなことしてる間にどんなタスクを登録すべきなのか忘れてしまいます。

問題発生

さてしばらくこの方法を使っていると、 todoとして登録している文字列の一部が検索で引っかからないことに気づきました。 具体的には、濁点・半濁点(パ行)などが引っかからないようでした。

調べてみると、 Raycastのスクリプト実行を通して入力されたタスク名で発生しているようでした。 そしてさらに調べると、その理由は例えば「パ」という文字が 「ハ」と「°」に分解されているというのが理由でした。2

これはシェルスクリプトに限らず、 Pythonを起動するような形式だとしても、 引数として渡された文字列で同様に発生している事象に見えました。

一方Raycastのスクリプト実行を経由しないでタスク登録した場合や、 Vim上で普通に日本語入力した場合は「パ」一文字になっているようでした。

問題の解決方法

なんでこんなことが起きているのかは気になりますが、 まずはこの問題を解決したいです。

そんな時は手っ取り早くChatGPTなどに聞いてしまうに限りますね。 実際にこんな感じに聞いてみました。

「パ」という文字が e38391 ではなく e3838fe3829a になってしまうことがあります。後者を前者に変換するにはどうしたらいいですか?

すると

echo "テキスト内にあるパとポを含むテキスト" | iconv -f utf-8 -t utf-8-mac | iconv -f utf-8-mac -t utf-8

こんなコマンドで変換できることを教えてくれました。 実際にシェルスクリプトに組み込むとこんな感じになります。

#!/bin/bash

# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title task
# @raycast.mode silent

# Optional parameters:
# @raycast.icon 🤖
# @raycast.argument1 {"type": "text", "placeholder": "task"}


task="$(iconv -f utf-8 -t utf-8-mac | iconv -f utf-8-mac -t utf-8 <<< $1)"

これでタスク登録を試してみるとバッチリ「パ」一文字の形で登録されており、 検索もきちんと引っかかるようになりました!

めでたしめでたし。

変換コマンドは何をやっているのか

めでたいことついでに、少しだけ変換コマンドについて調べてみました。 ただ文字コード周りは難しいのであまり深追いはしていません...。

iconvコマンドはmacOSであれば初めからインストールされているコマンドで、 文字コードの変換をしてくれるようです。 -fはfrom、-tはtoなので、 上記コマンドはある文字コードから文字コードへ変換して、 さらにそれをもう一度元の文字コードに戻しているようです。

utf-8-macはmacOSにおけるUnicode正規化を考慮した形式のようです。 (ここは用語の使い方として合っているのか定かではないです) 端的に使うとこんな感じです。

# utf-8-macに変換すると6バイト
$ echo "パ" | iconv -f utf-8 -t utf-8-mac | xxd
00000000: e383 8fe3 829a 0a                        .......

# utf-8に変換すると3バイト
$ echo "パ" | iconv -f utf-8-mac -t utf-8 | xxd
00000000: e383 910a                                ....

xxdはバイナリを16進数で表示させるコマンドで、0aは改行コードLFのことです。

Unicode正規化

Unicode正規化は

「パ」と「ハ」+「°」が違うバイナリ列だから検索で引っかからないのつらすぎ...。 とりあえずどこかに揃えた方がよくない?

という発想のものだと理解して良さそうです。

もう少し踏み込むと、 「1(全角)」と「1(半角)」を同一と見做すかなどの 「同じ概念のものは一つのものに統一させるべきか否か」 という辺りの規定も含んでいるようです。

なおmacOSはファイル名にNFDの亜種(分解できるものは分解していくという方針) を採用しているらしく、 内部的には「ハ」+「°」形式でデータ保存されているらしいです。

まとめ

Raycastのスクリプトの引数に濁点・半濁点の文字を渡すと、 「ハ」と「°」に分解された文字としてのデータが渡されるようです。 macで通常文字を入力した場合は「パ」一文字に対応したデータが用いられているようなので 両者は検索で引っかからないなどの問題が発生してしまいます。 これを回避するため、iconvを使って「パ」一文字の方に寄せるよう変換する方法をご紹介しました。

濁点・半濁点以外でこの問題が起きた場合にも 上記で示した変換方法で十全なのかはよくわかっていませんが、 少なくとも私が日本語環境で使っている上では、 この変換でそれ以上の問題は生じていない認識でいます。

Raycastのコマンドを定義すると ホットキーでいつでもどこからでも呼び出せるので 様々な場面で利用したくなりますね。 これで日本語でも問題なく使えそうなので色々活用していきたいです!

以上、誰かの参考になれば幸いです。

参照情報


  1. 残念ながら、利用できる引数の数は現在上限3つに限られています。これはドキュメントに「本当にそんなにいっぱい引数使う必要あるん?(意訳)」と書かれている通り、そんなにたくさんの引数が必要ならコマンドランチャーでやるべきじゃないのでは?という思想の表れだと思っています。 
  2. この記事の中で独立に存在する半濁点のマルは「25°C」などで用いられる「°」を用いており、Unicodeの半濁点を意味するコードポイント「0x309a」とは無関係のものを用いています。 

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.